package com.axonactive.yolo.validation;

import java.text.ParseException;
import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.axonactive.yolo.dto.Parameters;
import com.axonactive.yolo.util.Utils;

@Component
public class TaskValidator implements Validator {
	private static final Logger LOGGER = Logger.getLogger(TaskValidator.class);

	@Override
	public boolean supports(Class<?> clazz) {
		return Parameters.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		Parameters params = (Parameters) target;

		ValidationUtils.rejectIfEmpty(errors, "typeOfTrip",
				"typeOfTrip.notnull");
		ValidationUtils.rejectIfEmpty(errors, "fromLocation",
				"fromLocation.notnull");
		ValidationUtils.rejectIfEmpty(errors, "toLocation",
				"toLocation.notnull");
		ValidationUtils.rejectIfEmpty(errors, "outBound", "outBound.notnull");
		if (params.getTaskName().length() > 100) {
			errors.rejectValue("taskName", "taskName.outOfRange");
			params.setFromLocation("");
			params.setToLocation("");
		}
		// valid from & to Location
		if (!"".equals(params.getFromLocation()) && !"".equals(params.getToLocation()) && params.getFromLocation().trim()
				.equalsIgnoreCase(params.getToLocation().trim())) {
				errors.rejectValue("fromLocation", "from.to.Location.invalid");
				params.setFromLocation("");
				params.setToLocation("");
		}
		// Validate Date OutBound and InBound
		Date nowTemp = new Date();
		@SuppressWarnings("deprecation")
		Date now = new Date(nowTemp.getYear(), nowTemp.getMonth(),
				nowTemp.getDate());
		if ("".equals(params.getOutBound())) {
			try {
				Date departDate = Utils.SDF.parse(params.getOutBound().trim());
				if (departDate.getTime() < now.getTime()) {
					errors.rejectValue("outBound", "outBound.dateInPast");
					params.setFromLocation("");
					params.setToLocation("");
				}
			} catch (ParseException e) {
				errors.rejectValue("outBound", "outBound.cannotParseDate");
				params.setFromLocation("");
				params.setToLocation("");
				LOGGER.error("Date parse error", e);
			}
		}
		// validate normal
		if (!params.getMaxPrice().equals("")){
			double maxPrice=Double.parseDouble(params.getMaxPrice());
			if (maxPrice > 1000000000L) {
				errors.rejectValue("maxPrice", "maxPrice.outOfRange");
				params.setFromLocation("");
				params.setToLocation("");
			}
			
			if (maxPrice <= 0) {
				errors.rejectValue("maxPrice", "maxPrice.invalid");
				params.setFromLocation("");
				params.setToLocation("");
			}
		}
		// validate if RoundTrip
		if (!"".equals(params.getTypeOfTrip())
				&& "roundTrip".equals(params.getTypeOfTrip())) {
			ValidationUtils.rejectIfEmpty(errors, "inBound", "inBound.notnull");
			if (!"".equals(params.getOutBound()) && !"".equals(params.getInBound())) {
				try {
					Date departDate = Utils.SDF.parse(params.getOutBound().trim());
					Date returnDate = Utils.SDF.parse(params.getInBound().trim());
					if (departDate.getTime() > returnDate.getTime()) {
						errors.rejectValue("inBound",
								"inBound.lessThanOutBound");
						params.setFromLocation("");
						params.setToLocation("");
					}
				} catch (ParseException e) {
					LOGGER.error("Date parse error", e);
					errors.rejectValue("inBound", "inBound.cannotParseDate");
					params.setFromLocation("");
					params.setToLocation("");
				}
			}
		}

	}
}
